var publisher = {
  subscribers: {
    any: [] //事件 的类型，也就是订阅者  发布订阅模式
  },
  subscribe: function (fn, type) {
    var type = type || 'any'
    if (typeof this.subscribers[type] === 'undefined') {
      this.subscribers[type] = [];
    }
    this.subscribers[type].push(fn)
  },
  unsubscribe: function (fn, type) { //取消被订阅者
    this.visitSubscribers('unsubscribe', fn, type)
  },
  publish: function (publication, type) {
    this.visitSubscribers('publish', publication, type)
  },
  visitSubscribers: function (action, arg, type) {
    var pubtype = type || 'any',
      subscribers = this.subscribers[pubtype],
      i,
      max = subscribers.length;
    for (i = 0; i < max; i++) {
      if (action === 'publish') {
        subscribers[i](arg)
      } else {
        if (subscribers[i] === arg) {
          subscribers.splice(i, 1)
        }
      }
    }
  }
}

function makePublisher(o) {
  var i;
  for (i in publisher) {
    if (publisher.hasOwnProperty(i) && typeof publisher[i] === 'function') {
      o[i] = publisher[i]
    }
  }
  o.subscribers = {
    any: []
  };
}


var paper = { //发布者  发布日报和月刊
  daily: function () {
    this.publish('big news today') //调用订阅者的方法
  },
  monthly: function () {
    this.publish('interesting analysis', 'monthly')
  }
}

makePublisher(paper)

//订阅者
var joe = {
  drinkCoffee: function (paper) {
    console.log('Just read ' + paper)
  },
  sundayPreNap: function (monthly) {
    console.log('About to fall asleep reading this' + monthly)
  }
}

paper.subscribe(joe.drinkCoffee) //  paper注册joe
paper.subscribe(joe.sundayPreNap, 'monthly')

paper.daily()
paper.monthly()